package com.das.mechanic_base.utils;

import android.annotation.TargetApi;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;

import com.das.mechanic_base.app.X3MyApp;
import com.das.mechanic_base.gen.DaoSessionUtils;
import com.das.mechanic_base.gen.MethodTransferBean;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//保存方法调用
public class MethodTransferHelper {

    private MethodTransferHelper(){}
    private static class SingleInstance{
        private static final MethodTransferHelper mInstance = new MethodTransferHelper();
    }
    public static MethodTransferHelper getInstance(){
        return SingleInstance.mInstance;
    }

    /**
     * 传入的对象必须复现toString方法
     * @param clz
     * @param methodName
     * @param args
     */
    public void insertMethodTransfer(Class clz, String methodName,Object...args) {
        String tmpArgs = getArgs(args);
        ThreadPoolExecutor executor = getThreadExecutor();
        executor.execute(new MethodHelper(Status.INSERT, clz, methodName,tmpArgs));
    }

    private String getArgs(Object...args){
        StringBuilder sb = new StringBuilder();
        try {
            for(Object obj : args) {
                sb.append(" | ").append(obj.toString());
            }
            return sb.toString();
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }

    public static void doInsertMethodTransfer(Class clz, String methodName,String args) {
        synchronized (MethodTransferHelper.class) {
            String clsName = clz.getName();
            MethodTransferBean bean = new MethodTransferBean();
            String tel = (String) SpHelper.getData("mobile", "");
            bean.tel = tel;
            bean.clsName = clsName;
            bean.methodName = methodName;
            long millis =  System.currentTimeMillis();
            bean.timeMillis = millis + "";
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            Date date1 = new Date(millis);
            bean.time = format.format(date1);
            //制造商 （Manufacturer）,型号（Model）,品牌（Brand）,设备名 （Device）
            bean.device =  android.os.Build.MANUFACTURER + "|" + android.os.Build.MODEL + "|" + android.os.Build.BRAND + "|" + android.os.Build.DEVICE;
            PackageManager packageManager = X3MyApp.getInstance().getApp().getPackageManager();
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(X3MyApp.getInstance().getApp().getPackageName(), 0);
                bean.pkgName = packageInfo.packageName;
                int versionCode =  X3MyApp.getInstance().getApp().getPackageManager().getPackageInfo( X3MyApp.getInstance().getApp().getPackageName(),0).versionCode;
                bean.pkgVersionCode = versionCode + "";
                String verName = X3MyApp.getInstance().getApp().getPackageManager().getPackageInfo(X3MyApp.getInstance().getApp().getPackageName(),0).versionName;
                bean.pkgVersionName = verName;
            }catch (Exception e){
                e.printStackTrace();
            }
            bean.args = args;

            try {
                DaoSessionUtils.getInstance().insertMethodBean(bean);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void deleteAllMethodTransfer() {
        ThreadPoolExecutor executor = getThreadExecutor();
        executor.execute(new MethodHelper(Status.DEL));
    }

    public static void doDeleteAllUploadedMethodTransfer() {
        synchronized (MethodTransferHelper.class) {
            if (!X3StringUtils.isListEmpty(mList)){
                for (MethodTransferBean bean : mList){
                    DaoSessionUtils.getInstance().deleteMethodBean(bean);
                }
            }
        }
    }

    public static List<MethodTransferBean> searchAllMethodBean() {
        synchronized (MethodTransferHelper.class) {
            try {
                String tel = (String) SpHelper.getData("mobile", "");
                return DaoSessionUtils.getInstance().searchAllMethodBean(tel);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public void upLoad() {
        ThreadPoolExecutor executor = getThreadExecutor();
        executor.execute(new MethodHelper(Status.UPLOAD));
    }
    public static List<MethodTransferBean> mList ;
    private static void doUpLoad(){
        synchronized (MethodTransferHelper.class) {
            try {
                mList= searchAllMethodBean();
                if (!X3StringUtils.isListEmpty(mList)){
                    for (MethodTransferBean bean : mList){
//                        CrashReport.postCatchedException(new AppSelfException(bean.toString()));
                    }
                }
                doDeleteAllUploadedMethodTransfer();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private CommonThreadPool mUploadThreadPool;

    public synchronized ThreadPoolExecutor getThreadExecutor() {
        if (mUploadThreadPool == null || mUploadThreadPool.isShutdown()) {
            mUploadThreadPool = new CommonThreadPool(CORE_POOL_SIZE);
        }
        return mUploadThreadPool;
    }

    public static class CommonThreadPool extends ThreadPoolExecutor {

        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        public CommonThreadPool(int poolSize) {
            super(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingDeque<Runnable>(),
                    Executors.defaultThreadFactory(), new DiscardOldestPolicy());
        }
    }

    public static class MethodHelper implements Runnable {
        private String methodName;
        private Class clz;
        private String args;
        private Status code;

        public MethodHelper(Status code) {
            this.code = code;
        }

        public MethodHelper(Status code, Class clz, String methodName,String args) {
            this.code = code;
            this.clz = clz;
            this.methodName = methodName;
            this.args = args;
        }

        @Override
        public void run() {

            if (code == Status.DEL) { //删除
                doDeleteAllUploadedMethodTransfer();
            } else if (code == Status.UPLOAD) { // 上传
                doUpLoad();
            } else if (code == Status.INSERT) { // 插入
                doInsertMethodTransfer(clz, methodName,args);
            }

        }
    }

    private enum Status{
        UPLOAD,INSERT,DEL
    }

}
